home *** CD-ROM | disk | FTP | other *** search
/ Revista do CD-ROM 101 / CD-ROM 101.iso / compl / maya5ple / Install_MayaPLE5_English.exe / Maya / Data1.cab / createFlexorWin.mel < prev    next >
Encoding:
Text File  |  2003-07-17  |  17.0 KB  |  677 lines

  1. // Copyright (C) 1997-2002 Alias|Wavefront,
  2. // a division of Silicon Graphics Limited.
  3. //
  4. // The information in this file is provided for the exclusive use of the
  5. // licensees of Alias|Wavefront.  Such users have the right to use, modify,
  6. // and incorporate this code into other products for purposes authorized
  7. // by the Alias|Wavefront license agreement, without fee.
  8. //
  9. // ALIAS|WAVEFRONT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  10. // INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  11. // EVENT SHALL ALIAS|WAVEFRONT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  12. // CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  13. // DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  14. // TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  15. // PERFORMANCE OF THIS SOFTWARE.
  16. //
  17.  
  18. /////////////////////////////////////////////////////////////////////////
  19. //  Alias|Wavefront Script File
  20. //  MODIFY THIS AT YOUR OWN RISK
  21. //
  22. //  Creation Date:  May 1996
  23. //  Author(s):      Barb Balents
  24. //
  25. //  Description:
  26. //      Create and show a dialog for creating flexors.
  27. //
  28. /////////////////////////////////////////////////////////////////////////
  29.  
  30. //
  31. //  Procedure Name:
  32. //      handleExecError
  33. //
  34. //  Description:
  35. //              called to clean up when execFlexorCommand is called but the
  36. //              flexor that the user requested was not able to be created
  37. //              (The most likely source of error would be that the user
  38. //              had an invalid selection. For example, you can't make a joint
  39. //              flexor if you do not have a joint in your selection list.)
  40. //      
  41. //  Input Arguments:
  42. //              none 
  43. //
  44. //  Return Value:
  45. //      none
  46. //
  47. proc handleExecError(string $oldSelection[])
  48. {
  49.     // disable position flexor check box
  50.     //
  51.     checkBoxGrp -e -v1 0 positionBox;
  52.  
  53.     // restore the old selection list
  54.     //
  55.     if (size($oldSelection) > 0)
  56.     {
  57.         select -r $oldSelection;
  58.     }
  59.         
  60.     return;
  61. }
  62.  
  63. //
  64. //  Procedure Name:
  65. //      execFlexorCommand
  66. //
  67. //  Description:
  68. //              create a string corresponding to the flexor command based
  69. //              on the UI and execute it
  70. //      
  71. //  Input Arguments:
  72. //              none 
  73. //
  74. //  Return Value:
  75. //      none
  76. //
  77. global proc execFlexorCommand ()
  78. {
  79.     int $doTwoCommands = 0;
  80.     int $flexorIsLattice = 0;
  81.     int $flexorIsCluster = 0;       
  82.     int $atJoints = `checkBox -q -v allJoints` || `checkBox -q -v selJoints`;
  83.     int $atBones = `checkBox -q -v allBones` || `checkBox -q -v selBones`;
  84.  
  85.     // all segments but only selected joints or vice versa require
  86.     // different sets of flags so we need two commands
  87.     //
  88.     if ($atJoints && $atBones)
  89.     {
  90.         $doTwoCommands = 1;
  91.     }
  92.         
  93.     string $flexorType = `optionMenuGrp -q -v typeMenu`;
  94.     string $flexorType2;
  95.     string $whereString;
  96.     string $whereString2;
  97.     int $atBindPoseWarning = 0;
  98.  
  99.     $flexorIsLattice = ($flexorType == "lattice");
  100.     $flexorIsCluster = ($flexorType == "jointCluster");
  101.         
  102.     // If the flexor is a lattice, make it a joint or bone lattice
  103.     // according to whether the user asked to have it at bones
  104.     // or at joints.
  105.     //
  106.     // Two commands will be necessary if the user asked to have it
  107.     // at both joints and bones.
  108.     //
  109.     if ($flexorIsLattice)
  110.     {
  111.         string $bpNode[] = `dagPose -q -bp -sl`;
  112.         string $atBindPose[];
  113.         if (! catch ($atBindPose = `eval ("dagPose -q -ap "+$bpNode[0])`)) {
  114.             if (0 != size($atBindPose[0])) {
  115.                 $atBindPoseWarning = 1;
  116.             }
  117.         }
  118.         
  119.         if ($atJoints && $atBones)
  120.         {
  121.             $flexorType = "jointLattice";
  122.             $flexorType2 = "boneLattice";
  123.         }
  124.         else if ($atJoints)
  125.         {
  126.             $flexorType = "jointLattice";
  127.         }
  128.         else if ($atBones)
  129.         {
  130.             $flexorType = "boneLattice";
  131.         }
  132.         else
  133.         {
  134.             $flexorType = "lattice";
  135.         }
  136.     }
  137.     else if ($flexorIsCluster)
  138.     {
  139.         $flexorType = "jointCluster";
  140.     }
  141.     else if ($atJoints && $atBones)
  142.     {
  143.         $flexorType2 = $flexorType;
  144.     }
  145.  
  146.     // the whereString's are constructed according to the states of
  147.     // "At Selected Bones", "At All Bones", "At Selected Joints", "At All Joints"
  148.     //
  149.     if ($atJoints && $atBones) {
  150.         $whereString = " -aj ";
  151.         if (`checkBox -q -v allJoints`)
  152.             $whereString += "-ts ";
  153.         $whereString2 = " -ab ";
  154.         if (`checkBox -q -v allBones`)
  155.             $whereString2 += "-ts ";
  156.     } else if ($atJoints) {
  157.         if (`checkBox -q -v allJoints`)
  158.             $whereString = " -aj -ts ";
  159.         else
  160.             $whereString = " -aj ";
  161.     } else if ($atBones) {
  162.         if (`checkBox -q -v allBones`)
  163.             $whereString = "-ab -ts ";
  164.         else
  165.             $whereString = " -ab ";
  166.     }
  167.  
  168.     // start constructing the command string(s) that we will execute
  169.     //
  170.     string $deformCmd;
  171.     string $cmdString = "flexor -typ " + $flexorType + $whereString;
  172.     string $cmdString2 = "flexor -typ " + $flexorType2 + $whereString2;     
  173.  
  174.     // If it is a sculpt flexor, get the sculpt-specific data
  175.     // from the UI and add it to the flexor's -dc flag argument
  176.     //
  177.     if ($flexorType == "sculpt")
  178.     {
  179.         $deformCmd = "sculpt";
  180.                 
  181.         float $maxDisp = `floatSliderGrp -q -v maxFS`;
  182.         float $dropoff = `floatSliderGrp -q -v dropoffFS`;
  183.  
  184.         //      Get the sculpt object dropoff type from the
  185.         //      option menu
  186.         //
  187.         string $dropoffType = `optionMenuGrp -q -v sculptDropoffMenu`;
  188.         switch( $dropoffType ) {
  189.         case "None":
  190.             $dropoffType = "none";
  191.             break;
  192.         case "Linear":
  193.             $dropoffType = "linear";
  194.             break;
  195.         default:
  196.             $dropoffType = "none";
  197.             break;
  198.         }
  199.  
  200.         //      Get the sculpt object mode setting from
  201.         //      the option menu
  202.         //
  203.         string $mode = `optionMenuGrp -q -v sculptModeMenu`;
  204.         switch( $mode ) {
  205.         case "Flip":
  206.             $mode = "flip";
  207.             break;
  208.         case "Project":
  209.             $mode = "project";
  210.             break;
  211.         case "Stretch":
  212.             $mode = "stretch";
  213.             break;
  214.         default:
  215.             $mode = "stretch";
  216.             break;
  217.         }
  218.  
  219.         //      Get the sculpt object inside mode setting from
  220.         //      the option menu
  221.         //
  222.         string $insideMode = `optionMenuGrp -q -v sculptInsideMenu`;
  223.         switch( $insideMode ) {
  224.         case "Ring":
  225.             $insideMode = "ring";
  226.             break;
  227.         case "Even":
  228.             $insideMode = "even";
  229.             break;
  230.         default:
  231.             $insideMode = "ring";
  232.             break;
  233.         }
  234.  
  235.         $deformCmd += (" -mxd " + $maxDisp);
  236.         $deformCmd += (" -m " + $mode + " -im " + $insideMode);
  237.         $deformCmd += (" -drt " + $dropoffType + " -dds " + $dropoff);
  238.     }
  239.     // if it is a lattice flexor, get the lattice-specific data
  240.     // from the UI and add them to the flexor's -dc flag argument
  241.     //      
  242.     else if ($flexorIsLattice)
  243.     {
  244.         $deformCmd = "lattice";
  245.                 
  246.         int $sd, $td, $ud;
  247.         $sd = `intSliderGrp -q -v sDiv`;
  248.         $td = `intSliderGrp -q -v tDiv`;
  249.         $ud = `intSliderGrp -q -v uDiv`;
  250.         $deformCmd += (" -dv "+$sd+" "+$td+" "+$ud);
  251.  
  252.         $deformCmd += (" -cp ");
  253.     }
  254.  
  255.     // save the current selection so we can restore it later
  256.     //
  257.     string $selected[];
  258.     $selected = `ls -sl`;
  259.  
  260.     // actually execute the first command
  261.     //
  262.     string $results[];
  263.  
  264.     if (! $flexorIsCluster) {
  265.  
  266.         if ($flexorType == "jointLattice") {
  267.             $cmdString += " -dc " + ("\""+$deformCmd+" -dualBase true \"");
  268.         } else {
  269.             $cmdString += " -dc " + ("\""+$deformCmd+"\"");
  270.         }
  271.     }
  272.     if (catch ($results = `evalEcho $cmdString`) ||
  273.         0 == size($results))
  274.     {
  275.         // Return here and give the user another chance rather
  276.         // than removing the window.
  277.         //
  278.         if (0 == size($results))
  279.         {
  280.             // cleanup and return 
  281.             //
  282.             handleExecError($selected);
  283.             return;
  284.         }
  285.     }
  286.  
  287.     // we do two commands when there are conflicting flags:
  288.     //      * lattice at segments and at joints
  289.     //  * all segments but only selected joints or vice versa
  290.     //
  291.     if ($doTwoCommands)
  292.     {
  293.         if (size($selected) > 0) {
  294.             select -r $selected;
  295.         } else {
  296.             select -d;
  297.         }
  298.  
  299.         if (! $flexorIsCluster)
  300.             $cmdString2 += " -dc " + ("\""+$deformCmd+"\"");
  301.         catch ($results = `evalEcho $cmdString2`);
  302.     }
  303.  
  304.     // a 0-sized result signals failure. Return here and give the
  305.     // user another chance rather than removing the window.
  306.     //
  307.     if (0 == size($results))
  308.     {
  309.         // cleanup and return 
  310.         //
  311.         handleExecError($selected);
  312.         return;
  313.     }
  314.  
  315.     if ($atBindPoseWarning) {
  316.         warning("Skeleton was not at bindPose. Lattice flexors work best when created at bindPose.");
  317.     }
  318.     
  319.     // if the user clicked the positionBox, set the state on the
  320.     // invisible checkBox as a global variable
  321.     //
  322.     
  323.     if (`checkBoxGrp -q -v1 positionBox`) {
  324.         // select the transform above the lattice so that we can position it
  325.         //
  326.         string $currentSelection[];
  327.         $currentSelection = `ls -sl`;
  328.         
  329.         if ($flexorIsLattice && (1 == size($currentSelection)))
  330.         {
  331.             $positionedFlexorLattice=$currentSelection[0];
  332.             string $parents[];
  333.             $parents = `listRelatives -p`;
  334.             
  335.             if (size($parents) > 0)
  336.                 select -r $parents[0];
  337.         }
  338.         checkBoxGrp -e -v1 false positionBox;
  339.     } else {
  340.         select -r $selected;
  341.     }
  342.  
  343.     return;
  344. }
  345.  
  346. //      =============== updateFlexorTypeCB ========
  347. //
  348. // update callback for when the flexor type option is changed
  349. // 
  350. //
  351. global proc updateFlexorTypeCB()
  352. {
  353.     string $flexorType = `optionMenuGrp -q -v typeMenu`;
  354.  
  355.     frameLayout -e -enable true flexorBoneFrame;            
  356.  
  357.     if ($flexorType == "sculpt")
  358.     {
  359.         frameLayout -e -visible true sculptFrame;
  360.         frameLayout -e -visible false latticeFrame;
  361.         frameLayout -e -visible false clusterFrame;
  362.     }
  363.     else if ($flexorType == "jointCluster")
  364.     {
  365.         // bone flexors are not valid for joint clusters
  366.         //
  367.         frameLayout -e -enable false flexorBoneFrame;
  368.         checkBox -e -v 0 allBones;
  369.         checkBox -e -v 0 selBones;
  370.         frameLayout -e -visible true clusterFrame;
  371.         frameLayout -e -visible false latticeFrame;
  372.         frameLayout -e -visible false sculptFrame;
  373.     }       
  374.     else if ($flexorType == "lattice" ||
  375.              $flexorType == "jointLattice" ||
  376.              $flexorType == "boneLattice")
  377.     {
  378.         frameLayout -e -visible true latticeFrame;
  379.         frameLayout -e -visible false sculptFrame;
  380.         frameLayout -e -visible false clusterFrame;
  381.     }
  382. }
  383.  
  384. global proc jtsOrBonesCB ()
  385. //
  386. //      Description:
  387. //              callback for when selected joints/bones checkbox is clicked
  388. //
  389. {
  390.     int $atSelJoints = `checkBox -q -v selJoints`;
  391.     int $atSelBones = `checkBox -q -v selBones`;
  392.     int $atAllJoints = `checkBox -q -v allJoints`;
  393.     int $atAllBones = `checkBox -q -v allBones`;    
  394.  
  395.     // enable the positionBox if only one of either selJoints or
  396.     // selBones is true and neither allJoints nor allBones is on
  397.     //
  398.     if (($atSelJoints && $atSelBones) || $atAllJoints || $atAllBones)
  399.     {
  400.         checkBoxGrp -e -enable false positionBox;
  401.     }
  402.     else if ($atSelJoints || $atSelBones)
  403.     {
  404.         checkBoxGrp -e -enable true positionBox;
  405.     }
  406.     else
  407.     {
  408.         checkBoxGrp -e -enable false positionBox;
  409.     }
  410. }
  411.  
  412. //
  413. //  Procedure Name:
  414. //      createFlexorWin
  415. //
  416. //  Description:
  417. //              create and show a flexor-creation dialog      
  418. //
  419. //  Input Arguments:
  420. //              none   
  421. //
  422. //  Return Value:
  423. //              none
  424. //
  425. global proc createFlexorWin()
  426. {
  427.     string $winName = "createFlexorDialog";
  428.     
  429.     // if the window already exists, just pop it up to the top
  430.     //
  431.     if (`window -exists $winName`)
  432.     {
  433.         checkBoxGrp -e -v1 0 positionBox;
  434.         showWindow $winName;
  435.         return;
  436.     }
  437.     // create a new dialog and base container layout.
  438.     //
  439.     window -rtf false -ip
  440.         -mnb false -mxb false
  441.         -retain -s false
  442.         -wh 430 310
  443.         -tlc 120 740 
  444.         -t "Create Flexor" 
  445.         -iconName "Create Flexor"
  446.         $winName;
  447.  
  448.     if (`about -mac`) {
  449.         window -edit -h 325 $winName;
  450.     }        
  451.  
  452.     setUITemplate -pushTemplate DefaultTemplate;
  453.  
  454.     // ==================== FLEXOR TYPE OPTIONS =================/
  455.         
  456.     formLayout -nd 100 flexorMainForm;      
  457.  
  458.     formLayout flexorTypeForm;
  459.     optionMenuGrp -l "Flexor Type" 
  460.         -cw 1 80
  461.         -cc updateFlexorTypeCB typeMenu;
  462.  
  463.         // Get the available types and add them to an
  464.         // option menu
  465.         //
  466.         int $i;
  467.         string $flexList[];
  468.         $flexList = `flexor -q -l`;
  469.         $flexListCount = size($flexList);
  470.         
  471.         menuItem -l lattice latticeItem;
  472.         for ($i = 0; $i < $flexListCount; $i++)
  473.         {
  474.             if ($flexList[$i] != "lattice"
  475.                 &&  $flexList[$i] != "jointLattice"
  476.                 &&  $flexList[$i] != "boneLattice")
  477.             {
  478.                 menuItem -l $flexList[$i] ($flexList[$i] + "Item");
  479.             }
  480.         }
  481.  
  482.     setParent -m ..;
  483.  
  484.     button -l "Help..." -w 80 -c "showHelp CreateFlexor" helpButton;
  485.  
  486.     formLayout -e
  487.         -af typeMenu top 0
  488.         -af typeMenu bottom 0
  489.         -an typeMenu right 
  490.         -af typeMenu left 0
  491.  
  492.         -af helpButton top 0
  493.         -af helpButton bottom 0
  494.         -af helpButton right 0
  495.         -an helpButton left
  496.         flexorTypeForm;
  497.  
  498.     setParent flexorMainForm;
  499.         
  500.     // ==================== JOINT OPTIONS =================/
  501.  
  502.     frameLayout -l "Joints" 
  503.         -bv true -bs "etchedIn" -cll false -cl false
  504.         -la bottom -li 0 
  505.         flexorJointFrame;
  506.  
  507.     columnLayout -adj true -cal "left";
  508.  
  509.     checkBox -v 1 -l "At Selected Joint(s)  "
  510.         -onc "checkBox -e -v 0 allJoints; jtsOrBonesCB"
  511.         -ofc "jtsOrBonesCB"
  512.         selJoints;
  513.     checkBox -v 0 -l "At All Joint(s)"
  514.         -onc "checkBox -e -v 0 selJoints; jtsOrBonesCB"
  515.         -ofc "jtsOrBonesCB"
  516.         allJoints;      
  517.  
  518.     setParent flexorMainForm;
  519.  
  520.     // ==================== BONE OPTIONS =================/
  521.  
  522.     frameLayout -l "Bones" 
  523.         -bv true -bs "etchedIn" -cll false -cl false 
  524.         -la bottom -li 0 
  525.         flexorBoneFrame;
  526.  
  527.     columnLayout -adj true -cal "left";
  528.  
  529.     checkBox -v 0 -l "At Selected Bone(s)  "
  530.         -onc "checkBox -e -v 0 allBones; jtsOrBonesCB"
  531.         -ofc "jtsOrBonesCB"
  532.         selBones;
  533.     checkBox -v 0 -l "At All Bone(s)"
  534.         -onc "checkBox -e -v 0 selBones; jtsOrBonesCB"
  535.         -ofc "jtsOrBonesCB"
  536.         allBones;
  537.  
  538.     formLayout -e
  539.         -af flexorTypeForm top 5 
  540.         -af flexorTypeForm right 5
  541.         -af flexorTypeForm left 5
  542.         -an flexorTypeForm bottom
  543.  
  544.         -ac flexorJointFrame top 5 flexorTypeForm
  545.         -ap flexorJointFrame right 5 50
  546.         -af flexorJointFrame left 5
  547.  
  548.         -ac flexorBoneFrame left 5 flexorJointFrame
  549.         -ac flexorBoneFrame top 5 flexorTypeForm
  550.         -af flexorBoneFrame right 5
  551.         flexorMainForm;
  552.  
  553.     setParent flexorMainForm;
  554.  
  555.     // ==================== SPECIAL OPTIONS =================/
  556.     //
  557.     // These forms will hold special flexor options that vary depending
  558.     // on the flexor type. We leave them invisible and only show 
  559.     // them as needed.
  560.     //
  561.  
  562.     // ==================== SCULPT OPTIONS =================/
  563.         
  564.     setParent flexorMainForm;
  565.  
  566.     frameLayout -l "Sculpt Options"
  567.         -lv true -la bottom -li 0 
  568.         -bv true -bs "etchedIn"
  569.         -cll false -cl false 
  570.         -visible false 
  571.         sculptFrame;
  572.  
  573.     columnLayout -p sculptFrame -adj true -cw 100 cLayout;
  574.     floatSliderGrp -field true -l "Max Displacement" 
  575.         -min 0 -max 2 -pre 3 -step 0.1 maxFS;
  576.     floatSliderGrp -field true -l "Dropoff Distance" 
  577.         -min 0 -max 20 -pre 3 -step 0.1 dropoffFS;
  578.     columnLayout -co "left" 20;
  579.  
  580.     optionMenuGrp -l "Dropoff Type" -cc updateFlexorTypeCB sculptDropoffMenu;
  581.         menuItem -l "None";
  582.         menuItem -l "Linear";
  583.     setParent -m ..;
  584.  
  585.     optionMenuGrp -l "Mode" -cc updateFlexorTypeCB sculptModeMenu;
  586.         menuItem -l "Stretch";
  587.         menuItem -l "Flip";
  588.         menuItem -l "Project";
  589.     setParent -m ..;
  590.  
  591.     optionMenuGrp -l "Inside Mode" -cc updateFlexorTypeCB sculptInsideMenu;
  592.         menuItem -l "Ring";
  593.         menuItem -l "Even";
  594.     setParent -m ..;
  595.  
  596.     // ==================== LATTICE OPTIONS =================/
  597.  
  598.     setParent flexorMainForm;
  599.  
  600.     frameLayout -l "Lattice Options"
  601.         -lv true -la bottom -li 0 
  602.         -bv true -bs "etchedIn"
  603.         -cll false -cl false 
  604.         -visible true
  605.         latticeFrame;
  606.  
  607.     columnLayout -adj true -cw 100 cLayout2;
  608.     intSliderGrp -field true -l "S Divisions" -min 2 -max 20 -v 2 -step 1 sDiv;
  609.     intSliderGrp -field true -l "T Divisions" -min 2 -max 20 -v 5 tDiv;
  610.     intSliderGrp -field true -l "U Divisions" -min 2 -max 20 -v 2 uDiv;
  611.  
  612.     checkBoxGrp -v1 0 -l1 "Position the Flexor"
  613.         positionBox;
  614.         
  615.     // ==================== CLUSTER OPTIONS =================/
  616.     //
  617.     // No options - just inform the user
  618.  
  619.     setParent flexorMainForm;
  620.  
  621.     frameLayout -l "Cluster Options"
  622.         -lv true -la bottom -li 0 
  623.         -bv true -bs "etchedIn"
  624.         -cll false -cl false 
  625.         -visible false
  626.         clusterFrame;
  627.  
  628.     formLayout textForm;
  629.     text -l "No options for Joint Cluster flexors" noOptionText;
  630.     setParent ..;
  631.     formLayout -e
  632.         -af noOptionText left 80
  633.         -af noOptionText top 60
  634.         textForm;
  635.  
  636.     // ==================== CREATE and CLOSE Buttons =================/
  637.  
  638.     setParent flexorMainForm;
  639.  
  640.     button -l "Create" -w 100 -c execFlexorCommand okayButton;
  641.     button -l "Close" -w 100 -c "deleteUI createFlexorDialog" closeButton;
  642.  
  643.     formLayout -e
  644.         -af okayButton left 5
  645.         -an okayButton top
  646.         -ap okayButton right 5 50
  647.         -af okayButton bottom 5
  648.  
  649.         -ac closeButton left 5 okayButton
  650.         -af closeButton right 5
  651.         -an closeButton top
  652.         -af closeButton bottom 5
  653.  
  654.         -ac latticeFrame top 5 flexorBoneFrame
  655.         -af latticeFrame left 5
  656.         -af latticeFrame right 5
  657.         -ac latticeFrame bottom 5 okayButton
  658.  
  659.         -ac sculptFrame top 5 flexorBoneFrame
  660.         -af sculptFrame left 5
  661.         -af sculptFrame right 5
  662.         -ac sculptFrame bottom 5 okayButton
  663.  
  664.         -ac clusterFrame top 5 flexorBoneFrame
  665.         -af clusterFrame left 5
  666.         -af clusterFrame right 5
  667.         -ac clusterFrame bottom 5 okayButton
  668.         flexorMainForm; 
  669.  
  670.     updateFlexorTypeCB;
  671.  
  672.     setUITemplate -popTemplate;
  673.     showWindow $winName;
  674.  
  675. } // createFlexorWin //
  676.  
  677.